#include <memory>
#include <string>

using namespace std;

// 标准库是这样定义 move 的：
template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
    return static_cast<typename remove_reference<T>::type&&>(t);
}

int main()
{
    string s1("hi!"), s2;

    s2 = std::move(string("bye!")); // 正确：从一个右值移动数据
    // T = string
    // remove_reference<string>::type = string
    // string&& move(string&& t)
    // static_cast<string&&>(t)
    // t 的类型是 string&&，cast 什么都不做

    s2 = std::move(s1);             // 正确：但在赋值之后，s1 的值是不确定的
    // T = string&
    // remove_reference<string&>::type = string
    // string&& move(string& t)     // 引用折叠
    // static_cast<string&&>(t)
    // t 的类型是 string&，cast 将其转换为 string&&
}